

/**************************************************START OF FILE*****************************************************/



/*  ------------------------------------------------------------------------------------------------------------------
包含的头文件
*/

#include "stm32f0xx_hal.h"
#include "stdint.h"

#define FLASH_LAST_PAGE_ADDR (0x08000000 + 31 * 1024)


/*
*********************************************************************************************************************

@ Brief  : 读最后一页中存储的数据

@ Param  : Addr : 按两个字节计算

@ Return : NONE

@ Author : YWJ

*********************************************************************************************************************
*/
void xBSP_FLASH_ReadLastPage(uint32_t* pbuffer , uint16_t Len)
{
	for (uint16_t i = 0; i < Len; i++)
	{
		pbuffer[i] = ((uint32_t*)(FLASH_LAST_PAGE_ADDR))[i];
	}
}

/*
*********************************************************************************************************************

@ Brief  : 擦除最后一页中存储的数据

@ Param  : NONE

@ Return : NONE

@ Author : YWJ

*********************************************************************************************************************
*/
void MCUFLASH_EraseLastPage(void)
{
	FLASH_EraseInitTypeDef EraseInitStruct;
	uint32_t PageError = 0;
	HAL_FLASH_Unlock();
	//清除所有标志位
	__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP|FLASH_FLAG_WRPERR|FLASH_FLAG_PGERR);

	EraseInitStruct.TypeErase  = FLASH_TYPEERASE_PAGES;
	EraseInitStruct.PageAddress = FLASH_LAST_PAGE_ADDR;	
	EraseInitStruct.NbPages = 1;  
	
	/*校验标志*/
	if (HAL_FLASHEx_Erase(&EraseInitStruct, &PageError) != HAL_OK)
	{
		PageError = PageError;
	}
	HAL_FLASH_Lock();
}



/*
*********************************************************************************************************************

@ Brief  : 写最后一页中存储的数据

@ Param  : Addr : 按两个字节计算

@ Return : NONE

@ Author : YWJ

*********************************************************************************************************************
*/
void MCUFLASH_WriteLastPage(uint32_t* pbuffer , uint16_t Len)
{
	volatile HAL_StatusTypeDef FLASHStatus = HAL_OK;
	uint16_t dataIndex;

	/* Unlock the Flash  Program Erase controller */
	HAL_FLASH_Unlock();         //解锁
	__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP|FLASH_FLAG_WRPERR|FLASH_FLAG_PGERR);

	if(HAL_OK == FLASHStatus )
	{
		for(dataIndex = 0; dataIndex < Len; dataIndex++)
		{
			FLASHStatus = HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, FLASH_LAST_PAGE_ADDR + dataIndex * 4, pbuffer[dataIndex]);
		}
	}
	HAL_FLASH_Lock();//上锁保护
}



/*
*********************************************************************************************************************
@ Brief  : 写最后一页的数据
@ Param  : NONE
@ Return : NONE
@ Author : YWJ(QQ:872180981)
@ Data   : 2020-12-02 18:30
*********************************************************************************************************************
*/
void MCUFLASH_WriteLastPageAddr(uint32_t Addr , uint32_t pbuffer)
{
	volatile HAL_StatusTypeDef FLASHStatus = HAL_OK;

	/* Unlock the Flash  Program Erase controller */
	HAL_FLASH_Unlock();         //解锁
	__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP|FLASH_FLAG_WRPERR|FLASH_FLAG_PGERR);

	FLASHStatus = HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, FLASH_LAST_PAGE_ADDR + Addr * 4, pbuffer);

	HAL_FLASH_Lock();//上锁保护
}


/*
*********************************************************************************************************************

@ Brief  : 保存参数到Flash

@ Param  : NONE

@ Return : NONE

@ Author : YWJ

@ Data   : 2020-06-01 11:03

*********************************************************************************************************************
*/
void xBSP_FLASH_SaveData(uint32_t* pbuffer , uint16_t Len)
{
	//关闭中断
	__disable_irq(); //关闭所有中断
	//擦除
	MCUFLASH_EraseLastPage();

	//写入
	MCUFLASH_WriteLastPage(pbuffer , Len);

	//打开中断
	__enable_irq();//打开所有中断
}



/*
*********************************************************************************************************************
@ Brief  : 读取ID号并更新ID号
@ Param  : NONE
@ Return : NONE
@ Author : YWJ(QQ:872180981)
@ Data   : 2020-12-02 18:30
*********************************************************************************************************************
*/
uint32_t xBSP_FLASH_ReadWriteIndex(void)
{
	uint32_t i = 0;
	uint32_t CurrentCount;

	//查找没有写入的位置
	for (i = 30; i < 256; i++)
	{
		if(0xFFFFFFFF == ((uint32_t*)(FLASH_LAST_PAGE_ADDR))[i])
		{
			break;
		}
	}

	//完全空
	if(i == 30)
	{
		CurrentCount = 0;
	}
	else
	{
		CurrentCount = ((uint32_t*)(FLASH_LAST_PAGE_ADDR))[i-1];
		CurrentCount++;
	}
	
	//没有空余位置
	if(i == 256)
	{
		//保存数据
		uint32_t data[30];
		for (uint8_t j = 0; j < 30; j++)
		{
			data[j] =  ((uint32_t*)(FLASH_LAST_PAGE_ADDR))[j];
		}
		//保存数据
		xBSP_FLASH_SaveData(data , 30);
		i = 30;
	}

	//写入新的位置
	MCUFLASH_WriteLastPageAddr(i, CurrentCount);

	return (CurrentCount);
}




/**************************************************END OF FILE**********************************************************/
